package com.icesoft.core.web.suppose.setting;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import com.icesoft.core.web.suppose.setting.service.ISysSettingService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.icesoft.core.web.model.SysSettingDTO;
import com.icesoft.core.common.util.ReflectionUtils;

public abstract class BasePropertySetting<T extends Enum<? extends BaseSettingEnum>> {
    protected final Logger log = LoggerFactory.getLogger(this.getClass());
    @Autowired
    protected ISysSettingService sysSettingService;

    public abstract String getGroupName();

    protected String getProperty(T settingEnum) {
        String val = sysSettingService.findByGroup(getGroupName()).get(settingEnum.name());
        if (val == null) {
            BaseSettingEnum base = (BaseSettingEnum) settingEnum;
            val = base.getDefaultValue();
        }
        return val.trim();
    }

    protected boolean getBooleanProperty(T settingEnum) {
        String value = getProperty(settingEnum);
        return Boolean.valueOf(value);
    }

    protected int getIntProperty(T settingEnum) {
        String value = getProperty(settingEnum);
        if (!StringUtils.isNumeric(value)) {
            log.warn("错误的配置，要求数字类型，项【{}】值【{}】", settingEnum.name(), value);
            BaseSettingEnum base = (BaseSettingEnum) settingEnum;
            value = base.getDefaultValue();
        }
        return Integer.parseInt(value);
    }

    Class<Enum<? extends BaseSettingEnum>> clazz;

    public Map<String, String> getProperties() {
        return sysSettingService.findByGroup(getGroupName());
    }

    @SuppressWarnings("unchecked")
    @PostConstruct
    protected void register() {
        clazz = (Class<Enum<? extends BaseSettingEnum>>) ReflectionUtils.getGenricType(this.getClass());
        String groupName = getGroupName();
        if (!sysSettingService.findByGroup(groupName).isEmpty()) {
            return;
        }
        log.info("开始实例化配置：{}", groupName);
        List<SysSettingDTO> list = new ArrayList<>();
        for (Enum<? extends BaseSettingEnum> settingEnum : clazz.getEnumConstants()) {
			SysSettingDTO sysSetting = newSysSettingDTO(groupName, settingEnum);
            list.add(sysSetting);
        }
        sysSettingService.createSettings(list);
    }

    public int checkEveryPropertyRegister() {
        String groupName = getGroupName();
        log.info("开始检查“{}”中的每一条配置项是否生成", groupName);
        int count = 0;
        Map<String, String> propertyMap = sysSettingService.findByGroup(groupName);
        List<SysSettingDTO> list = new ArrayList<>();
        for (Enum<? extends BaseSettingEnum> settingEnum : clazz.getEnumConstants()) {
            String keyName = settingEnum.name();
            if (propertyMap.containsKey(keyName)) {
                log.info("配置项：{}存在", keyName);
                continue;
            }
            log.info("配置项：{}不存在，开始生成", keyName);
            SysSettingDTO sysSetting = newSysSettingDTO(groupName, settingEnum);
            list.add(sysSetting);
            count++;
        }
        sysSettingService.createSettings(list);
        return count;
    }

    private SysSettingDTO newSysSettingDTO(String groupName, Enum<? extends BaseSettingEnum> settingEnum) {
        SysSettingDTO sysSetting = new SysSettingDTO();
        sysSetting.setGroupName(groupName);
        sysSetting.setKeyName(settingEnum.name());
        BaseSettingEnum base = (BaseSettingEnum) settingEnum;
        sysSetting.setVal(base.getDefaultValue());
        sysSetting.setDes(base.getDes());
        return sysSetting;
    }

    public int clearProperties() {
        String groupName = getGroupName();
        Map<String, String> propertyMap = new HashMap<>(sysSettingService.findByGroup(groupName));
        for (Enum<? extends BaseSettingEnum> settingEnum : clazz.getEnumConstants()) {
            String keyName = settingEnum.name();
            propertyMap.remove(keyName);
        }
        if (propertyMap.isEmpty()) {
            return 0;
        }
        int count = 0;
        for (Map.Entry<String, String> entry : propertyMap.entrySet()) {
            log.info("清理“{}”中的无用配置项{}={}", groupName, entry.getKey(), entry.getValue());
            sysSettingService.remove(groupName, entry.getKey());
            count++;
        }
        return count;
    }
}
